package com.bifang.core.dict.integration.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.bifang.common.annotations.ApiService;
import com.bifang.common.annotations.OpApi;
import com.bifang.common.constant.CacheConst;
import com.bifang.common.constant.enums.common.BoolEnum;
import com.bifang.common.constant.enums.common.FuncTypeEnum;
import com.bifang.common.constant.enums.common.UserTypeEnum;
import com.bifang.common.constant.enums.dict.RoleDictEnum;
import com.bifang.common.constant.enums.dict.UserDictEnum;
import com.bifang.common.exception.AppException;
import com.bifang.common.helper.ApplicationContextHelper;
import com.bifang.common.helper.RedisHelper;
import com.bifang.common.interfaces.DictType;
import com.bifang.common.util.AntTreeUtil;
import com.bifang.common.util.PagerUtil;
import com.bifang.common.vo.AntTreeVO;
import com.bifang.common.vo.BaseVO;
import com.bifang.common.vo.DictDeleteVO;
import com.bifang.common.vo.DictFieldRetVO;
import com.bifang.common.vo.DictVO;
import com.bifang.common.vo.RoleVO;
import com.bifang.common.vo.SelectVO;
import com.bifang.common.vo.UserVO;
import com.bifang.common.vo.dict.CommonQueryVO;
import com.bifang.common.vo.dict.SearchQueryVO;
import com.bifang.common.vo.dict.SelectQueryVO;
import com.bifang.common.vo.dict.SelectResultVO;
import com.bifang.common.filter.xss.XssShieldUtil;
import com.bifang.core.dao.model.DictOrg;
import com.bifang.core.dao.model.DictSysRole;
import com.bifang.core.dao.model.DictSysUser;
import com.bifang.core.dao.model.DictSysUserBasic;
import com.bifang.core.dao.model.SysDict;
import com.bifang.core.dao.service.DictOrgService;
import com.bifang.core.dao.service.DictSysRoleService;
import com.bifang.core.dao.service.DictSysUserBasicService;
import com.bifang.core.dao.service.DictSysUserService;
import com.bifang.core.dao.service.SysDictService;
import com.bifang.core.dict.integration.DictIntegration;
import com.bifang.core.dict.util.CommonUtil;
import com.bifang.core.dict.util.UserSecureUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;

/** 数据字典服务 */
@Service
@ApiService(funcCode = "DICT", title = "数据字典服务")
public class DictIntegrationImpl implements DictIntegration {
    @Autowired SysDictService sysDictService;
    @Autowired
    RedisHelper redisHelper;
    @Autowired DictOrgService dictOrgService;
    @Autowired DictSysRoleService dictSysRoleService;
    @Autowired DictSysUserBasicService dictSysUserBasicService;
    @Autowired DictSysUserService dictSysUserService;

    private final String ModelHeadPath = "com.jwsoft.manager.dao.model";
    public static final String SUFFIX = "Name";
    private final int size = 100;
    /** 根据字段和key获取值 */
    @Override
    @OpApi(
            funcCode = "DICT0001",
            title = "获取数据字典值",
            funcType = FuncTypeEnum.query,
            publicFlag = BoolEnum.TRUE,
            savelog = false)
    public String getValue(String dictField, String dictKey) {
        if (StringUtils.isBlank(dictField) || StringUtils.isBlank(dictKey)) {
            return "";
        }
        List<SelectVO> selectVOList = getDictByDictField(dictField);
        if (CollectionUtils.isEmpty(selectVOList)) {
            return "";
        }
        Map<String, String> map =
                selectVOList.stream()
                        .collect(
                                Collectors.toMap(
                                        SelectVO::getDictKey,
                                        SelectVO::getDictValue,
                                        (k1, k2) -> k1));
        return map.get(dictKey);
    }

    @Override
    @OpApi(
            funcCode = "DICT0020",
            title = "根据数据字典value获取key",
            funcType = FuncTypeEnum.query,
            publicFlag = BoolEnum.TRUE,
            savelog = false)
    public String getKey(String dictField, String dictValue) {
        if (StringUtils.isBlank(dictField) || StringUtils.isBlank(dictValue)) {
            return "";
        }
        List<SelectVO> selectVOList = getDictByDictField(dictField);
        if (CollectionUtils.isEmpty(selectVOList)) {
            return "";
        }
        Map<String, String> map =
                selectVOList.stream()
                        .collect(
                                Collectors.toMap(
                                        SelectVO::getDictValue,
                                        SelectVO::getDictKey,
                                        (k1, k2) -> k1));
        return map.get(dictValue);
    }

    /** 根据字段获取字典值 */
    @Override
    @OpApi(
            funcCode = "DICT0002",
            title = "单个获取字段的下拉数据字典",
            funcType = FuncTypeEnum.query,
            publicFlag = BoolEnum.TRUE,
            savelog = false)
    public List<SelectVO> getDict(SelectVO selectVO) {
        Map<String, Object> map = BeanUtil.beanToMap(selectVO, true, true);
        if (map.size() > 1) {
            DictVO dictVO = Convert.convert(DictVO.class, selectVO);
            PageInfo<DictVO> pageInfo = getDictList(dictVO);
            if (CollectionUtils.isEmpty(pageInfo.getList())) {
                return new ArrayList<>();
            }
            List<SelectVO> selectVOList = Convert.toList(SelectVO.class, pageInfo.getList());
            return selectVOList;
        } else {
            return this.getDictByDictField(selectVO.getDictField());
        }
    }

    @Override
    public List<SelectVO> getDictByDictField(String dictField) {
        if (StringUtils.isBlank(dictField)) {
            return new ArrayList<>();
        }
        String key = dictField.toUpperCase();
        List<SelectVO> selectVOList = new ArrayList<>();
        if (redisHelper.hHasKey(CacheConst.SYS_DICT_VALUE, key)) {
            selectVOList = (List<SelectVO>) redisHelper.hget(CacheConst.SYS_DICT_VALUE, key);
        } else {
            QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
            queryWrapper
                    .lambda()
                    .eq(SysDict::getDel, BoolEnum.FALSE.getType())
                    .eq(SysDict::getStatus, BoolEnum.TRUE.getType())
                    .eq(SysDict::getDictField, key)
                    .orderByAsc(SysDict::getOrderNo);

            List<SysDict> sysDicts = sysDictService.list(queryWrapper);

            if (!CollectionUtils.isEmpty(sysDicts)) {
                selectVOList = Convert.toList(SelectVO.class, sysDicts);
                redisHelper.hset(CacheConst.SYS_DICT_VALUE, key, selectVOList, 172800);
            }
        }
        return selectVOList;
    }

    /**
     * 根据字段获取批量字典值
     *
     * @param dictFields 批量字段，用英文逗号隔开
     */
    @Override
    @OpApi(
            funcCode = "DICT0003",
            title = "批量获取字段的下拉数据字典",
            funcType = FuncTypeEnum.query,
            publicFlag = BoolEnum.TRUE,
            savelog = false)
    public Map<String, List<SelectVO>> getDictBatch(String dictFields) {
        Map<String, List<SelectVO>> map = new HashMap<>();
        if (StringUtils.isBlank(dictFields)) {
            return map;
        }
        List<String> dictFieldList =
                Arrays.stream(dictFields.split(",")).map(s -> s).collect(Collectors.toList());
        for (String dictField : dictFieldList) {
            map.put(dictField, getDictByDictField(dictField));
        }
        return map;
    }

    /**
     * 根据条件获取数据字典列表
     *
     * @param dictVO
     */
    @Override
    @OpApi(funcCode = "DICT0004", title = "根据条件查询数据字典列表", funcType = FuncTypeEnum.query)
    public PageInfo<DictVO> getDictList(DictVO dictVO) {
        SysDict query = Convert.convert(SysDict.class, dictVO);
        if (StringUtils.isBlank(query.getDel())) {
            query.setDel(BoolEnum.FALSE.getType());
        }
        if (StringUtils.isBlank(query.getStatus())) {
            query.setStatus(BoolEnum.TRUE.getType());
        }
        if (StringUtils.isBlank(dictVO.getOrgName()) && StringUtils.isNotBlank(dictVO.getOrgId())) {
            dictVO.setOrgNumber(getOrgCodeById(dictVO.getOrgId()));
        }
        Integer pageNum = dictVO.getPageNum();
        Integer pageSize = dictVO.getPageSize();
        if (pageNum != null && pageSize != null) {
            PageHelper.startPage(pageNum, pageSize);
        }
        List<DictVO> list = sysDictService.selectPageList(query);
        if (CollectionUtils.isEmpty(list)) {
            return PagerUtil.createEmptyPagerInfo(pageNum, pageSize);
        }
        PageInfo<DictVO> dictPageInfo = new PageInfo<>(list);
        return dictPageInfo;
    }

    @Override
    public List<DictVO> getDictListByDictField(String dictField) {
        QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(SysDict::getDictField, dictField)
                .eq(SysDict::getDel, BoolEnum.FALSE.getType());
        List<SysDict> list = sysDictService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        return Convert.toList(DictVO.class, list);
    }

    @Override
    @OpApi(
            funcCode = "DICT0005",
            title = "获取数据字典详情",
            funcType = FuncTypeEnum.query,
            savelog = false)
    public DictVO getDictDetail(DictVO dictVO) {
        Long sysId = dictVO.getSysId();
        if (sysId == null) {
            throw new AppException("字典id不能为空");
        }
        SysDict query = new SysDict();
        query.setSysId(sysId);
        query.setDel(BoolEnum.FALSE.getType());
        List<DictVO> list = sysDictService.selectPageList(query);
        if (CollectionUtils.isEmpty(list)) {
            throw new AppException("找不到数据字典信息");
        }
        return list.get(0);
    }

    @Override
    public DictVO getDictByFieldAndKey(String dictField, String dictKey) {
        QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(SysDict::getDel, BoolEnum.FALSE.getType())
                .eq(SysDict::getDictField, dictField.toUpperCase())
                .eq(SysDict::getDictKey, dictKey);
        SysDict sysDict = sysDictService.getOne(queryWrapper);
        if (sysDict != null) {
            DictVO dictVO = Convert.convert(DictVO.class, sysDict);
            return dictVO;
        }
        return null;
    }

    @Override
    @OpApi(
            funcCode = "DICT0006",
            title = "获取所有数据字典字段",
            funcType = FuncTypeEnum.query,
            publicFlag = BoolEnum.TRUE,
            savelog = false)
    public DictFieldRetVO getDictField(DictVO dictVO) {
        DictFieldRetVO retVO = new DictFieldRetVO();
        QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .select(SysDict::getDictField, SysDict::getFieldName)
                .eq(SysDict::getDel, BoolEnum.FALSE.getType())
                .groupBy(SysDict::getDictField)
                .groupBy(SysDict::getFieldName);
        List<SysDict> sysDicts = sysDictService.list(queryWrapper);
        if (!CollectionUtils.isEmpty(sysDicts)) {
            retVO.setFieldData(Convert.toList(SelectVO.class, sysDicts));
        } else {
            retVO.setFieldData(new ArrayList<>());
        }
        retVO.setKeyData(getDictByDictField(dictVO.getDictField()));
        return retVO;
    }

    @Override
    @Transactional
    @OpApi(funcCode = "DICT0007", title = "新增数据字典信息", funcType = FuncTypeEnum.insert)
    public DictVO add(DictVO dictVO) {
        if (dictVO.getSysId() != null) {
            throw new AppException("新增字典Id必须为空");
        }
        // 校验
        checkDict(dictVO, null);

        SysDict sysDict = Convert.convert(SysDict.class, dictVO);
        if (StringUtils.isNotBlank(dictVO.getOrgId())) {
            sysDict.setOrgNumber(getOrgCodeById(dictVO.getOrgId()));
        }
        sysDict.setDictField(sysDict.getDictField().toUpperCase());
        updateFieldName(dictVO);
        sysDictService.save(sysDict);
        dictVO.setSysId(sysDict.getSysId());
        this.clearCache(sysDict.getDictField());
        return getDictDetail(dictVO);
    }
    /** 校验重复 */
    private void checkDict(DictVO dictVO, SysDict oldDict) {
        if (StringUtils.isBlank(dictVO.getParentField())) {
            if (dictVO.getDictKey().equals(dictVO.getParentKey())) {
                throw new AppException("不能将自己作为父字典值");
            }
        } else {
            if (dictVO.getParentField().equals(dictVO.getDictField())) {
                if (dictVO.getDictKey().equals(dictVO.getParentKey())) {
                    throw new AppException("不能将自己作为父字典值");
                }
            }
        }
        boolean keyFlag = true;
        boolean valueFlag = true;
        if (oldDict != null) {
            if (oldDict.getDictField().equals(dictVO.getDictField())) {
                if (oldDict.getDictKey().equals(dictVO.getDictKey())) {
                    keyFlag = false;
                }
                if (oldDict.getDictValue().equals(dictVO.getDictValue())) {
                    valueFlag = false;
                }
            }
        }
        if (keyFlag) {
            QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
            queryWrapper
                    .lambda()
                    .eq(SysDict::getDel, BoolEnum.FALSE.getType())
                    .eq(SysDict::getDictKey, dictVO.getDictKey())
                    .eq(SysDict::getDictField, dictVO.getDictField().toUpperCase());
            long count = sysDictService.count(queryWrapper);
            if (count > 0) {
                throw new AppException("重复数据字典值");
            }
        }
        if (valueFlag) {
            QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
            queryWrapper
                    .lambda()
                    .eq(SysDict::getDel, BoolEnum.FALSE.getType())
                    .eq(SysDict::getDictValue, dictVO.getDictValue())
                    .eq(SysDict::getDictField, dictVO.getDictField().toUpperCase());
            long count = sysDictService.count(queryWrapper);
            if (count > 0) {
                throw new AppException("重复数据字典值名称");
            }
        }
        QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(SysDict::getDel, BoolEnum.FALSE.getType())
                .eq(SysDict::getFieldName, dictVO.getFieldName())
                .ne(SysDict::getDictField, dictVO.getDictField().toUpperCase());
        long count = sysDictService.count(queryWrapper);
        if (count > 0) {
            throw new AppException("重复字典字段名称");
        }
    }

    private void updateFieldName(DictVO dictVO) {
        QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .select(SysDict::getFieldName)
                .eq(SysDict::getDel, BoolEnum.FALSE.getType())
                .eq(SysDict::getDictField, dictVO.getDictField().toUpperCase())
                .groupBy(SysDict::getFieldName);
        List<SysDict> list = sysDictService.list(queryWrapper);
        if (!CollectionUtils.isEmpty(list)) {
            SysDict sysDict = list.get(0);
            if (!sysDict.getFieldName().equals(dictVO.getFieldName())) {
                UpdateWrapper<SysDict> updateWrapper = new UpdateWrapper<>();
                updateWrapper
                        .lambda()
                        .set(SysDict::getFieldName, dictVO.getFieldName())
                        .eq(SysDict::getDictField, dictVO.getDictField().toUpperCase())
                        .eq(SysDict::getDel, BoolEnum.FALSE.getType());
                sysDictService.update(updateWrapper);
            }
        }
    }

    @Override
    @Transactional
    @OpApi(funcCode = "DICT0008", title = "修改数据字典信息", funcType = FuncTypeEnum.update)
    public DictVO edit(DictVO dictVO) {
        SysDict oldDict = sysDictService.getById(dictVO.getSysId());
        if (oldDict == null) {
            throw new AppException("未找到需要修改的数据");
        }
        if (BoolEnum.TRUE.getType().equals(oldDict.getDel())) {
            throw new AppException("该数据已被删除");
        }
        // 校验
        checkDict(dictVO, oldDict);
        SysDict newDict = Convert.convert(SysDict.class, oldDict);
        BeanUtil.copyProperties(dictVO, newDict);
        updateFieldName(dictVO);
        if (StringUtils.isNotBlank(dictVO.getOrgId())) {
            newDict.setOrgNumber(getOrgCodeById(dictVO.getOrgId()));
        }
        sysDictService.updateById(newDict);
        this.clearCache(oldDict.getDictField());
        if (!dictVO.getDictField().equals(oldDict.getDictField())) {
            this.clearCache(dictVO.getDictField());
        }
        return getDictDetail(dictVO);
    }

    @Override
    @OpApi(funcCode = "DICT0009", title = "单个删除数据字典信息", funcType = FuncTypeEnum.delete)
    public void delete(DictDeleteVO dictVO) {
        SysDict sysDict = sysDictService.getById(dictVO.getSysId());
        if (sysDict == null) {
            throw new AppException("未找到需要删除的数据");
        }
        if (BoolEnum.TRUE.getType().equals(sysDict.getDel())) {
            throw new AppException("该数据已被删除");
        }

        sysDictService.removeById(dictVO.getSysId());
        this.clearCache(sysDict.getDictField());
    }

    @Override
    @OpApi(funcCode = "DICT0010", title = "批量删除数据字典信息", funcType = FuncTypeEnum.delete)
    public void deleteBatch(DictDeleteVO dictVO) {
        if (CollectionUtils.isEmpty(dictVO.getSysIds())) {
            throw new AppException("字典ID不能传空");
        }
        QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .in(SysDict::getSysId, dictVO.getSysIds())
                .eq(SysDict::getDel, BoolEnum.FALSE.getType());
        List<SysDict> list = sysDictService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            throw new AppException("未找到需要删除的数据");
        }
        List<String> dictFields = new ArrayList<>();
        for (SysDict sysDict : list) {
            if (!dictFields.contains(sysDict.getDictField())) {
                dictFields.add(sysDict.getDictField());
            }
        }
        sysDictService.removeByIds(dictVO.getSysIds());
        if (!CollectionUtils.isEmpty(dictFields)) {
            for (String dictField : dictFields) {
                this.clearCache(dictField);
            }
        }
    }

    @Override
    @OpApi(
            funcCode = "DICT0011",
            title = "清除数据字典缓存",
            funcType = FuncTypeEnum.other,
            publicFlag = BoolEnum.TRUE,
            savelog = false)
    public void clearCache(DictVO dictVO) {
        String dictField = dictVO.getDictField();
        this.clearCache(dictField);
    }

    public void clearCache(String dictField) {
        if (StringUtils.isNotBlank(dictField)) {
            dictField = dictField.toUpperCase();
            redisHelper.hdel(CacheConst.SYS_DICT_VALUE, dictField);
            redisHelper.hdel(CacheConst.SYS_ALL_DICT_COMMON_TREE, dictField.toUpperCase());
            if (dictField.equalsIgnoreCase("AREA")) {
                redisHelper.del(CacheConst.SYS_ALL_AREA_TREE);
            }
            if (dictField.equalsIgnoreCase("ICON")) {
                redisHelper.del(CacheConst.SYS_ALL_ICON_TREE);
            }
            if (dictField.equalsIgnoreCase("ORGTYPE")) {
                redisHelper.del(CacheConst.SYS_ALL_ORG_TYPE_TREE);
            }
            if (dictField.equalsIgnoreCase("USER")) {
                redisHelper.del(CacheConst.SYS_ALL_USER_DICT);
            }
        } else {
            redisHelper.del(CacheConst.SYS_DICT_VALUE);
            redisHelper.del(CacheConst.SYS_ALL_ORG_TYPE_TREE);
            redisHelper.del(CacheConst.SYS_ALL_ICON_TREE);
            redisHelper.del(CacheConst.SYS_ALL_DICT_COMMON_TREE);
            redisHelper.del(CacheConst.SYS_ALL_AREA_TREE);
            redisHelper.del(CacheConst.SYS_DICT_ORG_NAME_ID);
            redisHelper.del(CacheConst.SYS_DICT_ORG_NAME_CODE);
            redisHelper.del(CacheConst.SYS_DICT_ORG_ID_CODE);
            redisHelper.del(CacheConst.SYS_DICT_ORG_CODE_ID);
            redisHelper.del(CacheConst.SYS_ALL_USER_DICT);
            redisHelper.del(CacheConst.SYS_ORG_TREE_BY_TYPE);
            redisHelper.del(CacheConst.SYS_ALL_ORG_TREE);
            redisHelper.del(CacheConst.SYS_ALL_ORG_TREE_CODE);
            redisHelper.del(CacheConst.SYS_ALL_USER_DICT_ORGID);
            redisHelper.del(CacheConst.SYS_ALL_USER_DICT_ORG);
            redisHelper.del(CacheConst.SYS_ALL_USER_DICT_ROLEID);
        }
    }

    @Override
    @OpApi(
            funcCode = "DICT0012",
            title = "根据组织id获取名称",
            funcType = FuncTypeEnum.query,
            publicFlag = BoolEnum.TRUE,
            savelog = false)
    public String getOrgNameById(String orgId) {
        if (StringUtils.isBlank(orgId)) {
            return "";
        }
        Map<Object, Object> map = new HashMap<>();
        if (redisHelper.hasKey(CacheConst.SYS_DICT_ORG_NAME_ID)) {
            map = redisHelper.hmget(CacheConst.SYS_DICT_ORG_NAME_ID);
        } else {
            map.putAll(setCacheOrgMap("1"));
        }
        if (map.get(orgId) != null) {
            return map.get(orgId).toString();
        } else {
            return "";
        }
    }

    @Override
    @OpApi(
            funcCode = "DICT0013",
            title = "根据组织编码获取名称",
            funcType = FuncTypeEnum.query,
            publicFlag = BoolEnum.TRUE,
            savelog = false)
    public String getOrgNameByCode(String orgCode) {
        if (StringUtils.isBlank(orgCode)) {
            return "";
        }
        Map<Object, Object> map = new HashMap<>();
        if (redisHelper.hasKey(CacheConst.SYS_DICT_ORG_NAME_CODE)) {
            map = redisHelper.hmget(CacheConst.SYS_DICT_ORG_NAME_CODE);
        } else {
            map.putAll(setCacheOrgMap("2"));
        }
        if (map.get(orgCode) != null) {
            return map.get(orgCode).toString();
        } else {
            return "";
        }
    }

    @Override
    @OpApi(
            funcCode = "DICT0014",
            title = "根据组织编码获取ID",
            funcType = FuncTypeEnum.query,
            publicFlag = BoolEnum.TRUE,
            savelog = false)
    public String getOrgIdByCode(String orgCode) {
        if (StringUtils.isBlank(orgCode)) {
            return "";
        }
        Map<Object, Object> map = new HashMap<>();
        if (redisHelper.hasKey(CacheConst.SYS_DICT_ORG_ID_CODE)) {
            map = redisHelper.hmget(CacheConst.SYS_DICT_ORG_ID_CODE);
        } else {
            map.putAll(setCacheOrgMap("3"));
        }
        if (map.get(orgCode) != null) {
            return map.get(orgCode).toString();
        } else {
            return "";
        }
    }

    @Override
    @OpApi(
            funcCode = "DICT0015",
            title = "根据组织id获取编码",
            funcType = FuncTypeEnum.query,
            publicFlag = BoolEnum.TRUE,
            savelog = false)
    public String getOrgCodeById(String orgId) {
        if (StringUtils.isBlank(orgId)) {
            return "";
        }
        Map<Object, Object> map = new HashMap<>();
        if (redisHelper.hasKey(CacheConst.SYS_DICT_ORG_CODE_ID)) {
            map = redisHelper.hmget(CacheConst.SYS_DICT_ORG_CODE_ID);
        } else {
            map.putAll(setCacheOrgMap("4"));
        }
        if (map.get(orgId) != null) {
            return map.get(orgId).toString();
        } else {
            return "";
        }
    }

    private Map<String, Object> setCacheOrgMap(String OrgMapType) {
        QueryWrapper<DictOrg> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(DictOrg::getDel, BoolEnum.FALSE.getType());
        List<DictOrg> dictOrgList = dictOrgService.list(queryWrapper);
        if (CollectionUtils.isEmpty(dictOrgList)) {
            return new HashMap<>();
        }
        Map<String, Object> nameIdMap =
                dictOrgList.stream()
                        .collect(
                                Collectors.toMap(
                                        DictOrg::getOrgId, DictOrg::getOrgName, (k1, k2) -> k1));
        redisHelper.hmset(CacheConst.SYS_DICT_ORG_NAME_ID, nameIdMap, 86400);
        Map<String, Object> nameCodeMap =
                dictOrgList.stream()
                        .collect(
                                Collectors.toMap(
                                        DictOrg::getOrgCode, DictOrg::getOrgName, (k1, k2) -> k1));
        redisHelper.hmset(CacheConst.SYS_DICT_ORG_NAME_CODE, nameCodeMap, 86400);
        Map<String, Object> idCodeMap =
                dictOrgList.stream()
                        .collect(
                                Collectors.toMap(
                                        DictOrg::getOrgCode, DictOrg::getOrgId, (k1, k2) -> k1));
        redisHelper.hmset(CacheConst.SYS_DICT_ORG_ID_CODE, idCodeMap, 86400);
        Map<String, Object> codeIdMap =
                dictOrgList.stream()
                        .collect(
                                Collectors.toMap(
                                        DictOrg::getOrgId, DictOrg::getOrgCode, (k1, k2) -> k1));
        redisHelper.hmset(CacheConst.SYS_DICT_ORG_CODE_ID, codeIdMap, 86400);
        if ("1".equals(OrgMapType)) {
            return nameIdMap;
        } else if ("2".equals(OrgMapType)) {
            return nameCodeMap;
        } else if ("3".equals(OrgMapType)) {
            return idCodeMap;
        } else if ("4".equals(OrgMapType)) {
            return codeIdMap;
        }
        return new HashMap<>();
    }

    @Override
    @OpApi(
            funcCode = "DICT0016",
            title = "获取通用数据字典树",
            funcType = FuncTypeEnum.query,
            publicFlag = BoolEnum.TRUE,
            savelog = false)
    public List<AntTreeVO> getDictCommonTree(String dictField) {
        if (StringUtils.isBlank(dictField)) {
            return new ArrayList<>();
        }
        dictField = dictField.toUpperCase();
        List<AntTreeVO> antTreeVOS = new ArrayList<>();
        if (redisHelper.hHasKey(CacheConst.SYS_ALL_DICT_COMMON_TREE, dictField)) {
            antTreeVOS =
                    (List<AntTreeVO>)
                            redisHelper.hget(CacheConst.SYS_ALL_DICT_COMMON_TREE, dictField);
            return antTreeVOS;
        }
        DictVO query = new DictVO();
        query.setDictField(dictField);
        query.setStatus(BoolEnum.TRUE.getType());
        List<DictVO> dictVOList = this.getDictList(query).getList();
        Map<String, Object> map = new HashMap<>();
        map.put("title", "title");
        for (DictVO dictVO : dictVOList) {
            AntTreeVO antTreeVO = new AntTreeVO();
            antTreeVO.setKey(dictVO.getDictKey());
            // 选择后获取的值
            antTreeVO.setValue(dictVO.getDictKey());
            antTreeVO.setParentKey(dictVO.getParentKey());
            antTreeVO.setTitle(dictVO.getDictValue());
            antTreeVO.setScopedSlots(map);
            antTreeVOS.add(antTreeVO);
        }

        antTreeVOS = AntTreeUtil.constructTaskDTOToTree(antTreeVOS);
        // 进缓存
        redisHelper.hset(CacheConst.SYS_ALL_DICT_COMMON_TREE, dictField, antTreeVOS, 86400);
        return antTreeVOS;
    }
    /** indata和notIndata 只能到省级 */
    @Override
    @OpApi(
            funcCode = "DICT0017",
            title = "获取全国行政区划字典树",
            funcType = FuncTypeEnum.query,
            publicFlag = BoolEnum.TRUE,
            savelog = false)
    public List<AntTreeVO> getAreaSelectTree(List<String> inData, List<String> notInData) {
        if (!CollectionUtils.isEmpty(inData) && !CollectionUtils.isEmpty(notInData)) {
            throw new AppException("包含和剔除只能选择一种");
        }
        String key = "all";
        if (!CollectionUtils.isEmpty(inData)) {
            key = JSONUtil.toJsonStr(inData);
        }
        if (!CollectionUtils.isEmpty(notInData)) {
            key = JSONUtil.toJsonStr(notInData);
        }
        key = SecureUtil.md5(key);
        List<AntTreeVO> antTreeVOS = new ArrayList<>();
        if (redisHelper.hHasKey(CacheConst.SYS_ALL_AREA_TREE, key)) {
            antTreeVOS = (List<AntTreeVO>) redisHelper.hget(CacheConst.SYS_ALL_AREA_TREE, key);
            return antTreeVOS;
        }
        DictVO query = new DictVO();
        query.setDictField("AREA");
        query.setStatus(BoolEnum.TRUE.getType());
        List<DictVO> dictVOList = this.getDictList(query).getList();
        if (CollectionUtils.isEmpty(dictVOList)) {
            return new ArrayList<>();
        }
        Map<String, Object> map = new HashMap<>();
        map.put("title", "title");
        for (DictVO dictVO : dictVOList) {
            AntTreeVO antTreeVO = new AntTreeVO();
            antTreeVO.setKey(dictVO.getDictKey());
            // 选择后获取的值
            antTreeVO.setValue(dictVO.getDictKey());
            antTreeVO.setParentKey(dictVO.getParentKey());
            antTreeVO.setTitle(dictVO.getDictValue());
            antTreeVO.setScopedSlots(map);
            antTreeVOS.add(antTreeVO);
        }

        antTreeVOS = AntTreeUtil.constructTaskDTOToTree(antTreeVOS);
        List<AntTreeVO> retList = new ArrayList<>();
        boolean flag = true;
        if (!CollectionUtils.isEmpty(inData)) {
            for (AntTreeVO antTreeVO : antTreeVOS) {
                if (inData.contains(antTreeVO.getKey())) {
                    retList.add(antTreeVO);
                }
            }
            flag = false;
        }
        if (!CollectionUtils.isEmpty(notInData)) {
            for (AntTreeVO antTreeVO : antTreeVOS) {
                if (!notInData.contains(antTreeVO.getKey())) {
                    retList.add(antTreeVO);
                }
            }
            flag = false;
        }
        if (flag) {
            retList.addAll(antTreeVOS);
        }
        // 进缓存
        redisHelper.hset(CacheConst.SYS_ALL_AREA_TREE, key, retList, 86400);
        return retList;
    }

    /** 图标下拉树 */
    @Override
    @OpApi(
            funcCode = "DICT0018",
            title = "获取图标下拉树",
            funcType = FuncTypeEnum.query,
            publicFlag = BoolEnum.TRUE,
            savelog = false)
    public List<AntTreeVO> getIconSelectTree(BaseVO baseVO) {
        List<AntTreeVO> antTreeVOS = new ArrayList<>();
        if (redisHelper.hasKey(CacheConst.SYS_ALL_ICON_TREE)) {
            antTreeVOS = (List<AntTreeVO>) redisHelper.get(CacheConst.SYS_ALL_ICON_TREE);
            return antTreeVOS;
        }
        DictVO query = new DictVO();
        query.setDictField("ICON");
        query.setStatus(BoolEnum.TRUE.getType());
        List<DictVO> dictVOList = this.getDictList(query).getList();
        Map<String, Object> map = new HashMap<>();
        map.put("title", "title");
        for (DictVO dictVO : dictVOList) {
            AntTreeVO antTreeVO = new AntTreeVO();
            antTreeVO.setKey(dictVO.getDictKey());
            // 选择后获取的值
            antTreeVO.setValue(dictVO.getDictKey());
            antTreeVO.setParentKey(dictVO.getParentKey());
            antTreeVO.setTitle(dictVO.getDictValue());
            if (!"leaf".equalsIgnoreCase(dictVO.getClassify())) {
                antTreeVO.setSelectable(false);
                antTreeVO.setDisabled(true);
                antTreeVO.setDisableCheckbox(true);
                antTreeVO.setTitle(dictVO.getDictValue());
            }
            antTreeVO.setScopedSlots(map);
            antTreeVOS.add(antTreeVO);
        }

        antTreeVOS = AntTreeUtil.constructTaskDTOToTree(antTreeVOS);
        // 进缓存
        redisHelper.set(CacheConst.SYS_ALL_ICON_TREE, antTreeVOS, 86400);
        return antTreeVOS;
    }

    @Override
    public UserVO getUserDetail(String userId) {
        if (StringUtils.isBlank(userId)) {
            return null;
        }
        if (redisHelper.hHasKey(CacheConst.SYS_USER_ID, userId)) {
            return (UserVO) redisHelper.hget(CacheConst.SYS_USER_ID, userId);
        }
        DictSysUser sysUser = dictSysUserService.getById(userId);
        if (sysUser == null) {
            return null;
        }
        if (BoolEnum.TRUE.getType().equals(sysUser.getDel())) {
            return null;
        }
        UserVO userVO = Convert.convert(UserVO.class, sysUser);
        DictSysUserBasic sysUserBasic = dictSysUserBasicService.getById(userId);
        if (sysUserBasic != null) {
            if (sysUserBasic.getDel().equals(BoolEnum.FALSE.getType())) {
                BeanUtils.copyProperties(sysUserBasic, userVO);
            }
        }
        // 解密用户被加密的字段
        UserSecureUtil.aesDecryptUser(userVO);
        // 转义数据字典值
        valueToName(userVO, Arrays.asList(UserDictEnum.values()));
        userVO.setOrgName(this.getOrgNameById(userVO.getOrgId()));
        userVO.setOrgCode(this.getOrgCodeById(userVO.getOrgId()));
        userVO.setUserPassword(null);
        if (StringUtils.isBlank(userVO.getFullName())) {
            userVO.setFullName(XssShieldUtil.analysisXss(userVO.getFullName()));
        }
        redisHelper.hset(CacheConst.SYS_USER_ID, userId, userVO);
        return userVO;
    }

    @Override
    public String getFullNameByUserId(String userId) {
        if (StringUtils.isBlank(userId)) {
            return "";
        }
        UserVO userVO = this.getUserDetail(userId);
        if (userVO == null) {
            return "";
        }
        return userVO.getFullName();
    }

    @Override
    public RoleVO getRoleDetail(String roleId) {
        if (StringUtils.isBlank(roleId)) {
            return null;
        }
        if (redisHelper.hHasKey(CacheConst.SYS_ROLE_ID, roleId)) {
            return (RoleVO) redisHelper.hget(CacheConst.SYS_ROLE_ID, roleId);
        }
        DictSysRole sysRole = dictSysRoleService.getById(roleId);
        if (sysRole == null) {
            return null;
        }
        if (BoolEnum.TRUE.getType().equals(sysRole.getDel())) {
            return null;
        }
        RoleVO roleVO = Convert.convert(RoleVO.class, sysRole);
        valueToName(roleVO, Arrays.asList(RoleDictEnum.values()));
        redisHelper.hset(CacheConst.SYS_ROLE_ID, roleId, roleVO);
        return null;
    }

    @Override
    public String getRoleNameById(String roleId) {
        if (StringUtils.isBlank(roleId)) {
            return "";
        }
        RoleVO roleVO = this.getRoleDetail(roleId);
        if (roleVO == null) {
            return "";
        }
        return roleVO.getRoleName();
    }

    @Override
    @OpApi(
            funcCode = "DICT0019",
            title = "根据过滤条件获取下拉字典",
            funcType = FuncTypeEnum.query,
            publicFlag = BoolEnum.TRUE,
            savelog = false)
    public List<SelectVO> getDictCondition(SelectVO selectVO, String dictKeys) {
        if (StringUtils.isBlank(selectVO.getDictField())) {
            return new ArrayList<>();
        }
        String dictfield = selectVO.getDictField().toUpperCase();
        QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(SysDict::getDel, BoolEnum.FALSE.getType())
                .eq(SysDict::getStatus, BoolEnum.TRUE.getType())
                .eq(SysDict::getDictField, dictfield)
                .orderByAsc(SysDict::getOrderNo);

        if (StringUtils.isNotBlank(selectVO.getClassify())) {
            queryWrapper.lambda().eq(SysDict::getClassify, selectVO.getClassify());
        }
        if (StringUtils.isNotBlank(selectVO.getParentKey())) {
            queryWrapper.lambda().eq(SysDict::getParentKey, selectVO.getParentKey());
        }
        if (StringUtils.isNotBlank(dictKeys)) {
            String[] dictkeyList = dictKeys.split(",");
            queryWrapper.lambda().in(SysDict::getDictKey, dictkeyList);
        }

        List<SysDict> sysDicts = sysDictService.list(queryWrapper);
        return Convert.toList(SelectVO.class, sysDicts);
    }

    @Override
    public List<SelectResultVO> getSelectData(SelectQueryVO vo) {
        Class daoBeanNew = CommonUtil.getClass(vo.getTableName());
        if (daoBeanNew == null) {
            throw new AppException("传入的表实体类不存在！");
        }
        try {
            String beanName = daoBeanNew.getSimpleName();
            Object implBean = ApplicationContextHelper.getBean(getImplClassName(beanName));
            QueryWrapper<Object> queryWrapper = new QueryWrapper<>();
            for (CommonQueryVO item : vo.getQueryList()) {
                if (item.getFieldValue() instanceof List<?>) {
                    List<String> fieldList =
                            (Convert.toList(String.class, item.getFieldValue()))
                                    .stream()
                                            .filter(StringUtils::isNotBlank)
                                            .collect(Collectors.toList());
                    if (fieldList.size() > 0) {
                        queryWrapper.in(item.getFieldName(), fieldList);
                    }
                } else if (item.getFieldValue() instanceof String) {
                    if (StringUtils.isNotBlank((String) item.getFieldValue())) {
                        queryWrapper.eq(item.getFieldName(), item.getFieldValue());
                    }
                }
            }
            int cSize = vo.getSize() <= 0 ? size : vo.getSize();
            queryWrapper.last("limit " + cSize);
            Method implMethod =
                    ReflectionUtils.findMethod(implBean.getClass(), "list", Wrapper.class);
            assert implMethod != null;
            Object invoke = implMethod.invoke(implBean, queryWrapper);
            List<Object> resultObjectList = Convert.toList(Object.class, invoke);
            List<SelectResultVO> resultVOList = new ArrayList<>();
            for (Object o : resultObjectList) {
                Method keyMethod =
                        ReflectionUtils.findMethod(
                                daoBeanNew,
                                "get" + CommonUtil.toUpperCaseFirstOne(vo.getKeyName()));
                Method valueMethod =
                        ReflectionUtils.findMethod(
                                daoBeanNew,
                                "get" + CommonUtil.toUpperCaseFirstOne(vo.getValueName()));
                SelectResultVO resultVO = new SelectResultVO();
                assert keyMethod != null;
                assert valueMethod != null;
                resultVO.setKeyName(vo.getKeyName());
                resultVO.setDictKey(keyMethod.invoke(o).toString());
                resultVO.setValueName(vo.getValueName());
                resultVO.setDictValue(valueMethod.invoke(o).toString());
                resultVO.setTableName(vo.getTableName());
                resultVOList.add(resultVO);
            }
            return resultVOList;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public PageInfo<?> getCommonData(SearchQueryVO vo) {
        Class daoBean = CommonUtil.getClass(vo.getTableName());
        if (daoBean == null) {
            throw new AppException("传入的表实体类不存在！");
        }
        try {

            String beanName = daoBean.getSimpleName();
            Object implBean = ApplicationContextHelper.getBean(getImplClassName(beanName));
            QueryWrapper<Object> queryWrapper = new QueryWrapper<>();
            for (CommonQueryVO item : vo.getQueryList()) {
                if (item.getFieldValue() instanceof List<?>) {
                    List<String> fieldList =
                            (Convert.toList(String.class, item.getFieldValue()))
                                    .stream()
                                            .filter(StringUtils::isNotBlank)
                                            .collect(Collectors.toList());
                    if (fieldList.size() > 0) {
                        queryWrapper.in(
                                item.getFieldName(),
                                fieldList.stream().filter(StringUtils::isNotBlank).toArray());
                    }
                } else if (item.getFieldValue() instanceof String) {
                    if (StringUtils.isNotBlank((String) item.getFieldValue())) {
                        queryWrapper.eq(item.getFieldName(), item.getFieldValue());
                    }
                }
            }
            if (StringUtils.isNotBlank(vo.getSearchText())
                    && StringUtils.isNotBlank(vo.getSearchField())) {
                List<String> fieldList =
                        Arrays.stream(vo.getSearchField().split(","))
                                .map(s -> s)
                                .collect(Collectors.toList());
                if (fieldList.size() > 1) {
                    queryWrapper.and(
                            wrapper -> {
                                wrapper.or(
                                        orWrapper -> {
                                            for (String field : fieldList) {
                                                orWrapper.like(field, vo.getSearchText());
                                            }
                                        });
                            });

                } else {
                    queryWrapper.like(vo.getSearchField(), vo.getSearchText());
                }
            }
            String fieldName = CommonUtil.getFieldName(daoBean, vo.getKeyName());
            if (!CollectionUtils.isEmpty(vo.getSelectList())) {
                if (StringUtils.isNotBlank(fieldName)) {
                    queryWrapper.notIn(fieldName, vo.getSelectList());
                }
            }
            if (!CollectionUtils.isEmpty(vo.getAscList())) {
                for (String ascValue : vo.getAscList()) {
                    queryWrapper.orderByAsc(ascValue);
                }
            }
            if (!CollectionUtils.isEmpty(vo.getDescList())) {
                for (String descValue : vo.getDescList()) {
                    queryWrapper.orderByDesc(descValue);
                }
            }
            Method implMethod =
                    ReflectionUtils.findMethod(implBean.getClass(), "list", Wrapper.class);
            assert implMethod != null;
            List<Object> resultList = new ArrayList<>();

            // 获取已选择的数据
            List<Object> selectData = null;
            if (!CollectionUtils.isEmpty(vo.getSelectList())) {
                if (StringUtils.isNotBlank(fieldName)) {
                    QueryWrapper<Object> selectQuery = new QueryWrapper<>();
                    selectQuery.in(fieldName, vo.getSelectList());
                    Object invokeSelect = implMethod.invoke(implBean, selectQuery);
                    selectData = Convert.toList(daoBean, invokeSelect);

                } else {
                    throw new AppException(
                            "在实体类" + daoBean.getSimpleName() + "中未找到字段" + vo.getKeyName());
                }
            }
            // 开启分页
            if (vo.getPageNum() == null) {
                vo.setPageNum(1);
            }
            if (vo.getPageSize() == null) {
                vo.setPageSize(100);
            }
            if (vo.getPageNum() != null && vo.getPageSize() != null) {
                PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
            }
            Object invoke = implMethod.invoke(implBean, queryWrapper);
            List<Object> searchList = Convert.toList(daoBean, invoke);
            if (!CollectionUtils.isEmpty(searchList)) {
                resultList.addAll(searchList);
            }
            if (!CollectionUtils.isEmpty(selectData)) {
                resultList.addAll(selectData);
            }
            if (CollectionUtils.isEmpty(resultList)) {
                // 判断是否为空，为空则返回空参数
                return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
            }
            resultList.forEach(
                    item -> {
                        Field[] fields = item.getClass().getDeclaredFields();
                        Arrays.stream(fields)
                                .filter(
                                        field ->
                                                !vo.getResultList().contains(field.getName())
                                                        && !field.getName().equals(vo.getKeyName())
                                                        && !field.getName()
                                                                .equals(vo.getValueName()))
                                .forEach(
                                        field -> {
                                            try {
                                                field.setAccessible(true);
                                                if (!"serialVersionUID".equals(field.getName())) {
                                                    field.set(item, null);
                                                }
                                            } catch (Exception e) {
                                                e.printStackTrace();
                                            }
                                        });
                    });
            // 不为空则获取分页结果
            PageInfo<JSONObject> pageInfo = new PageInfo<>();
            // 转义数据字典值
            //            dictUtil.valueToName(actorList, Arrays.asList(ActorDictEnum.values()));
            return PagerUtil.parsePagerVo(
                    JSONUtil.parseArray(resultList).toList(JSONObject.class), pageInfo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
    }

    @Override
    public List<String> getUserTypeList(String userType) {
        List<String> list = new ArrayList<>();
        QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .eq(SysDict::getStatus, BoolEnum.TRUE.getType())
                .eq(SysDict::getDictField, "USERTYPE")
                .eq(SysDict::getDictKey, userType);
        List<SysDict> sysDictList = sysDictService.list(queryWrapper);
        if (CollectionUtils.isEmpty(sysDictList)) {
            list.add(userType);
            return list;
        }
        SysDict sysDict = sysDictList.get(0);
        if (StringUtils.isBlank(sysDict.getParentKey()) || "#".equals(sysDict.getParentKey())) {
            QueryWrapper<SysDict> queryWrapperP = new QueryWrapper<>();
            queryWrapperP
                    .lambda()
                    .eq(SysDict::getStatus, BoolEnum.TRUE.getType())
                    .eq(SysDict::getDictField, "USERTYPE")
                    .eq(SysDict::getParentKey, userType);
            List<SysDict> sysDicts = sysDictService.list(queryWrapperP);
            if (!CollectionUtils.isEmpty(sysDicts)) {
                for (SysDict dict : sysDicts) {
                    list.add(dict.getDictKey());
                }
            }
            list.add(userType);
        } else {
            QueryWrapper<SysDict> queryWrapperW = new QueryWrapper<>();
            queryWrapperW
                    .lambda()
                    .eq(SysDict::getStatus, BoolEnum.TRUE.getType())
                    .eq(SysDict::getDictField, "USERTYPE")
                    .eq(SysDict::getParentKey, sysDict.getParentKey());
            List<SysDict> sysDicts = sysDictService.list(queryWrapperW);
            if (!CollectionUtils.isEmpty(sysDicts)) {
                for (SysDict dict : sysDicts) {
                    list.add(dict.getDictKey());
                }
            } else {
                list.add(userType);
            }
            list.add(sysDict.getParentKey());
        }
        if (!UserTypeEnum.USER.getType().equals(userType)) {
            if (!UserTypeEnum.SUP_ADMIN.getType().equals(userType)) {
                list.add(UserTypeEnum.SUP_ADMIN.getType());
            }
        }
        return list;
    }

    private String getImplClassName(String name) {

        String beanName = CommonUtil.toLowerCaseFirstOne(name) + "ServiceImpl";

        return beanName;
    }

    @Override
    public List<AntTreeVO> getDictConditionTree(SelectVO selectVO) {
        if (StringUtils.isBlank(selectVO.getDictField())) {
            return new ArrayList<>();
        }
        selectVO.setDictField(selectVO.getDictField());
        List<AntTreeVO> antTreeVOS = new ArrayList<>();
        DictVO query = new DictVO();
        query.setDictField(selectVO.getDictField());
        query.setStatus(BoolEnum.TRUE.getType());
        if (StringUtils.isNotBlank(selectVO.getDictField())) {
            query.setClassify(selectVO.getClassify());
        }
        if (StringUtils.isNotBlank(selectVO.getOrgId())) {
            query.setOrgId(selectVO.getOrgId());
        }
        List<DictVO> dictVOList = this.getDictList(query).getList();
        Map<String, Object> map = new HashMap<>();
        map.put("title", "title");
        for (DictVO dictVO : dictVOList) {
            AntTreeVO antTreeVO = new AntTreeVO();
            antTreeVO.setKey(dictVO.getDictKey());
            // 选择后获取的值
            antTreeVO.setValue(dictVO.getDictKey());
            antTreeVO.setParentKey(dictVO.getParentKey());
            antTreeVO.setTitle(dictVO.getDictValue());
            antTreeVO.setScopedSlots(map);
            antTreeVOS.add(antTreeVO);
        }

        antTreeVOS = AntTreeUtil.constructTaskDTOToTree(antTreeVOS);
        return antTreeVOS;
    }

    public <T> void valueToName(T data, List<DictType> dictTypeList) {
        valueToName(Arrays.asList(data), dictTypeList);
    }

    public <T> void valueToName(List<T> dataList, List<DictType> dictTypeList) {
        if (CollectionUtils.isEmpty(dataList) || CollectionUtils.isEmpty(dictTypeList)) {
            return;
        }
        // 查询字典值列表
        Map<String, List<SelectVO>> dictDataVOList = getDictDataList(dictTypeList);
        if (CollectionUtils.isEmpty(dictDataVOList)) {
            return;
        }

        for (T data : dataList) {
            setValue(data, dictTypeList, dictDataVOList, 1);
        }
    }

    private Map<String, List<SelectVO>> getDictDataList(List<DictType> dictTypeList) {
        if (CollectionUtils.isEmpty(dictTypeList)) {
            return new HashMap<>();
        }
        Map<String, List<SelectVO>> map = new HashMap<>();
        for (DictType dictType : dictTypeList) {
            List<SelectVO> result = getDictByDictField(dictType.getDictField().toUpperCase());
            if (!CollectionUtils.isEmpty(result)) {
                map.put(dictType.getPropertyName(), result);
            }
        }
        return map;
    }

    private <T> void setValue(
            T data,
            List<DictType> dictTypeList,
            Map<String, List<SelectVO>> dictDataVOList,
            Integer count) {
        if (count > 10) {
            return;
        }
        Class cls = data.getClass();
        String typeName = cls.getTypeName();
        if (typeName.indexOf("java.lang") >= 0
                || typeName.indexOf("java.util") >= 0
                || typeName.indexOf("java.math") >= 0) {
            return;
        }
        // 最多10层转换
        count = count + 1;
        BeanWrapper beanWrapper = new BeanWrapperImpl(data);
        int size = dictTypeList.size();
        // 挨个转义字典值
        for (int i = 0; i < size; i++) {
            DictType dictType = dictTypeList.get(i);
            String property = dictType.getPropertyName();
            String nameProperty = property + SUFFIX;

            String dictKey = getDictValue(data, property);
            if (dictKey == null) {
                continue;
            }
            SelectVO dictDataVO = filter(dictDataVOList.get(dictType.getPropertyName()), dictKey);
            if (dictDataVO != null && beanWrapper.isWritableProperty(nameProperty)) {
                beanWrapper.setPropertyValue(nameProperty, dictDataVO.getDictValue());
            }
        }

        Field[] fields = cls.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field f = fields[i];
            boolean isStatic = Modifier.isStatic(f.getModifiers());
            if (isStatic) { // 静态变量不处理
                continue;
            }
            f.setAccessible(true);
            String type = f.getType().getTypeName().toLowerCase();
            if (type.indexOf("java.lang") < 0
                    && type.indexOf("java.util") < 0
                    && type.indexOf("java.math") < 0) {
                Object obj = beanWrapper.getPropertyValue(f.getName());
                if (obj != null) {
                    setValue(obj, dictTypeList, dictDataVOList, count);
                }
            }
            if (type.indexOf("list") > 0) {
                List<T> list = (List) beanWrapper.getPropertyValue(f.getName());
                if (!CollectionUtils.isEmpty(list)) {
                    for (T obj : list) {
                        setValue(obj, dictTypeList, dictDataVOList, count);
                    }
                }
            }
        }
    }

    private SelectVO filter(List<SelectVO> dictDataVOList, String dictKey) {
        return CollectionUtils.isEmpty(dictDataVOList)
                ? null
                : dictDataVOList.stream()
                        .filter(dictDataVO -> dictDataVO.getDictKey().equals(dictKey))
                        .findFirst()
                        .orElse(null);
    }

    private <T> String getDictValue(T data, String property) {
        BeanWrapper beanWrapper = new BeanWrapperImpl(data);
        // 字典属性和字典名称属性必须有效
        if (!beanWrapper.isReadableProperty(property)) {
            return null;
        }
        Object obj = beanWrapper.getPropertyValue(property);
        if (obj == null) {
            return null;
        }
        try {
            return obj.toString();
        } catch (Exception e) {
            return null;
        }
    }
}
